package parser;

enum LexSymbol {
	ADD, SUBTRACT, MULTIPLY, DIVIDE, NUMBER, LEFT_PAREN, RIGHT_PAREN, SIN, 
	COS, TAN, POW, CARROT, VAR, SPACE, SQRT, UNARYMINUS, COMMA, EOF;
	
	public static LexSymbol getInstance(String token) throws LexError{
		if(token.equals("+")){
			return LexSymbol.ADD;
		}else if(token.equals("-")){
			return LexSymbol.SUBTRACT;
		}else if(token.equals("*")){
			return LexSymbol.MULTIPLY;
		}else if(token.equals("/")){
			return LexSymbol.DIVIDE;
		}else if(token.equals("(")){
			return LexSymbol.LEFT_PAREN;
		}else if(token.equals(")")){
			return LexSymbol.RIGHT_PAREN;
		}else if(token.equals("\n")){
			return LexSymbol.EOF;
		}else if(token.equalsIgnoreCase("sin")){
			return LexSymbol.SIN;
		}else if(token.equalsIgnoreCase("cos")){
			return LexSymbol.COS;
		}else if(token.equalsIgnoreCase("tan")){
			return LexSymbol.TAN;
		}else if(token.equalsIgnoreCase("^")){
			return LexSymbol.CARROT;
		}else if(token.equalsIgnoreCase("x")){
			return LexSymbol.VAR;
		}else if(token.equalsIgnoreCase(" ")){
			return LexSymbol.SPACE;
		}else if(token.equalsIgnoreCase("pow")){
			return LexSymbol.POW;
		}else if(token.equalsIgnoreCase("sqrt")){
			return LexSymbol.SQRT;
		}else if(token.equalsIgnoreCase("~")){
			return LexSymbol.UNARYMINUS;
		}else if(token.equalsIgnoreCase(",")){
			return LexSymbol.COMMA;
		}else {
			try{
				Double.parseDouble(token);
				return LexSymbol.NUMBER;
			}catch(NumberFormatException nfe){
				throw new LexError("Unrecognized Symbol");
			}
		}
	}
	
	public static int getPrecedence(LexSymbol lex){
		switch (lex){
		case ADD:
		case SUBTRACT:
			return 1;
		case MULTIPLY:
		case DIVIDE:
		case SIN:
		case TAN:
		case COS:
			return 2;
		case UNARYMINUS:
			return 3;
		case CARROT:
		case POW:
		case SQRT:
			return 4;
		case NUMBER:
		case VAR:
			return 5;
		}
		return -1;
	}
	
	public static boolean isLeftAssociative(LexSymbol lex){
		switch (lex){
		case CARROT:
		case POW:
		case SIN:
		case COS:
		case TAN:
		case SQRT:
		case UNARYMINUS:
			return false;
		}
		return true;
	}
}
